/***************************************************
 ** Create by Hasaki on 2021/11/25.
 ** This file is part of the CSTL project.
 ** This file follows version 3 of GNU License.
 ** About GNU, see <https://www.gnu.org/licenses/>.
 **
 ** 本文件由Hasaki(间宫羽咲sama)于2021年11月25日创建。
 ** 本文件是CSTL(C-STL)项目的一部分。
 ** 本文件遵从GNU-v3协议。
 ** 关于GNU协议，见<https://www.gnu.org/licenses/>。
 ***************************************************/
#include <stdio.h>
#include "HskUtil.h"
#include "HskVector.h"

void PrintLongLongFun (Vector *const _this, void *data, size_t seq) {
  printf("%zu: %lld\n", seq, *(long long *)data);
}

void LongLongFoo1 (Vector *const _this, void *data, size_t seq) {
  *(long long *)data = seq * 7;
}

int main() {
  printf("\n--- Testing: Function HskPower2Ceil in HskUtil.h ---\n\n");
  for (size_t i=0;i<10;++i)
      printf("i=%X, HskPower2Ceil=%zu\n", i, HskPower2Ceil(i));

  printf("\n--- Testing: Function VecCreate in HskVector.h ---\n\n");
  Vector* vec1 = VecCreate(sizeof(long long), 3, 5);
  VecDispMsg(vec1);                                   // expected: this.size = 3, this.capa = 5, this.typesize = 8.
  Vector* vec2 = VecCreate(sizeof(long long), 5, 3);  // expected: [VecCreate PARM WARN]: size 5 > capacity 3 is unexpected, already let capacity = size.
  VecDispMsg(vec2);                                   // expected: this.size = 5, this.capa = 5, this.typesize = 8.

  printf("\n--- Testing: Function VecReSize in HskVector.h ---\n\n");
  VecReSize(vec1, 4);
  VecDispMsg(vec1);                                   // expected: this.size = 4, this.capa = 5, this.typesize = 8.
  VecReSize(vec1, 6);
  VecDispMsg(vec1);                                   // expected: this.size = 6, this.capa = 6, this.typesize = 8.
  VecReSize(vec1, 5);                                 // expected: [VecReSize WARN]: newSize 5 < size 6, so size will be cropped.
  VecDispMsg(vec1);                                   // expected: this.size = 5, this.capa = 6, this.typesize = 8.

  printf("\n--- Testing: Function VecReCapa in HskVector.h ---\n\n");
  VecReCapa(vec2, 7);
  VecDispMsg(vec2);                                   // expected: this.size = 5, this.capa = 7, this.typesize = 8.
  VecReCapa(vec2, 3);                                 // expected: [VecReCapa WARN]: newCapa 3 < size 5, so size will be cropped.
  VecDispMsg(vec2);                                   // expected: this.size = 3, this.capa = 3, this.typesize = 8.
  VecReCapa(vec2, 0);                                 // expected: [VecReCapa WARN]: newCapa 0 < size 3, so size will be cropped.
  VecDispMsg(vec2);                                   // expected: this.size = 0, this.capa = 0, this.typesize = 8.

  printf("\n--- Testing: Function VecDelete in HskVector.h ---\n\n");
  VecDelete(&vec2);
  printf("vec2 = %zu\n", vec2);                       // expected: vec2 = 0
  VecDelete(&vec2);                                   // expected: [VecClean NULL WARN]: ATTENTION! pointer _this == NULL, already return.
  VecReCapa(vec2, 5);                                 // expected: [VecReCapa NULL WARN]: ATTENTION! pointer _this == NULL, already return.
  VecGetSize(vec2);                                   // expected: [VecGetSize NULL WARN]: ATTENTION! pointer _this == NULL, already return.
  VecGetCapa(vec2);                                   // expected: [VecGetCapa NULL WARN]: ATTENTION! pointer _this == NULL, already return.
  VecDispMsg(vec2);                                   // expected: [VecDispMsg NULL WARN]: ATTENTION! pointer _this == NULL, already return.
  vec2 = VecCreate(sizeof(long long), 3, 5);
  VecDispMsg(vec2);                                   // expected: this.size = 3, this.capa = 5, this.typesize = 8.
  VecDelete(&vec2);
  printf("vec2 = %zu\n", vec2);                       // expected: vec2 = 0

  printf("\n--- Testing: Function VecHandleAll in HskVector.h ---\n\n");
  VecHandleAll(vec1, LongLongFoo1);
  VecHandleAll(vec1, PrintLongLongFun);               // expected: 0: 0
                                                      // expected: 1: 7
                                                      // expected: 2: 14
                                                      // expected: 3: 21
                                                      // expected: 4: 28
  printf("vec1[2] = %lld\n", *(long long*)VecGet(vec1, 2));
                                                      // expected: vec1[2] = 14
  *(long long*)VecGet(vec1, 2) = 100;
  VecHandleAll(vec1, PrintLongLongFun);               // expected: 0: 0
                                                      // expected: 1: 7
                                                      // expected: 2: 100
                                                      // expected: 3: 21
                                                      // expected: 4: 28

  printf("\n--- Testing: Function VecPush in HskVector.h ---\n\n");
  vec2 = VecCreate(sizeof(long long), 0, 0);
  VecDispMsg(vec2);                                   // expected: this.size = 0, this.capa = 0, this.typesize = 8.
  VecPushSlice(vec2, vec1->_begin, vec1->_end);
  VecDispMsg(vec2);                                   // expected: this.size = 5, this.capa = 8, this.typesize = 8.
  VecHandleAll(vec2, PrintLongLongFun);               // expected: 0: 0
                                                      // expected: 1: 7
                                                      // expected: 2: 100
                                                      // expected: 3: 21
                                                      // expected: 4: 28
  long long val = 114;
  VecPush(vec1, &val);
  VecDispMsg(vec1);                                   // expected: this.size = 6, this.capa = 6, this.typesize = 8.
  val = 514;
  VecPush(vec1, &val);
  val = 1919810;
  VecPush(vec1, &val);
  VecDispMsg(vec1);                                   // expected: this.size = 8, this.capa = 8, this.typesize = 8.
  VecHandleAll(vec1, PrintLongLongFun);               // expected: 0: 0
                                                      // expected: 1: 7
                                                      // expected: 2: 100
                                                      // expected: 3: 21
                                                      // expected: 4: 28
                                                      // expected: 5: 114
                                                      // expected: 6: 514
                                                      // expected: 7: 1919810
  val = 19260817;
  VecPush(vec1, &val);
  VecDispMsg(vec1);                                   // expected: this.size = 9, this.capa = 16, this.typesize = 8.
  VecHandleAll(vec1, PrintLongLongFun);               // expected: 0: 0
                                                      // expected: 1: 7
                                                      // expected: 2: 100
                                                      // expected: 3: 21
                                                      // expected: 4: 28
                                                      // expected: 5: 114
                                                      // expected: 6: 514
                                                      // expected: 7: 1919810
                                                      // expected: 8: 19260817
  VecDelN(vec1, 6);
  VecDispMsg(vec1);                                   // expected: this.size = 3, this.capa = 16, this.typesize = 8.
  printf("vec1[4] = %lld\n", *(long long*)VecGet(vec1, 4));
                                                      // expected: [VecGet PARM WARN]: N 4 >= size 3 is unexpected, capacity = 16.
                                                      // expected: vec1[4] = 0
  VecDelN(vec1, 3);                                   // expected: [VecDelN WARN]: size 3 but delete 3, so all space be freed.
  VecDispMsg(vec1);                                   // expected: this.size = 0, this.capa = 0, this.typesize = 8.

  getchar();
  return 0;
}
